#pragma once

#include<QString>
#include<QIcon>
#include<QUuid>
#include<QDateTime>
#include<QFile>
#include<QDebug>
#include<QFileInfo>

//创建一个命名空间
namespace model{

static inline QString getFileName(const QString& path){
    QFileInfo fileInfo(path);
    return fileInfo.fileName();
}

#define TAG QString("[%1:%2]").arg(model::getFileName(__FILE__),QString::number(__LINE__))
#define LOG() qDebug().noquote() << TAG

//工具函数
static inline QString formatTime(int64_t timestamp){
    //先把时间戳转换为dateTime对象，再转成格式化时间
    QDateTime dateTime = QDateTime::fromSecsSinceEpoch(timestamp);
    return dateTime.toString("MM-dd HH:mm::ss");
}

//通过这个函数，获得秒级的时间
static inline int64_t getTime(){
    return  QDateTime::currentSecsSinceEpoch();
}

//根据QByteArray,转成QIcon
static inline QIcon makeIcon(const QByteArray& byteArray){
    QPixmap pixmap;
    pixmap.loadFromData(byteArray);
    QIcon icon(pixmap);
    return icon;
}

//从指定文件中，读取所有的二进制内容，得到一个QByteArray
static inline QByteArray loadFileToQByteArray(const QString& path){
    QFile file(path);
    if(!file.open(QFile::ReadOnly)){
        LOG()<<"文件打开失败";
        return QByteArray();
    }
    QByteArray content = file.readAll();
    file.close();
    return content;
}

//把QByteArray中的内容，写入到某个指定文件里
static inline void writeFileToFile(const QString& path,const QByteArray& content){
    QFile file(path);
    if(!file.open(QFile::WriteOnly)){
        LOG()<<"文件打开失败";
        return;
    }
    file.write(content);
    file.flush();
    file.close();
}

//用户信息
class UserInfo{
public:
    QString userId = "";        //用户编号
    QString nickName = "";      //用户昵称
    QString description = "";   //用户签名
    QString phone = "";         //用户电话
    QIcon avatar = QIcon();     //用户头像
};

//消息类型
enum MessageType{
    TEXTTYPE,           //文本消息
    IMAGETYPE,          //图片消息
    FILETYPE,           //文件消息
    SPEECHTYPE,         //语音消息
};

//消息信息
class Message{
    QString messageId = "";             //消息编号
    QString chatSessionId = "";         //会话编号
    QString time = "";                  //消息时间，通过格式化时间方式来表示，如 06-07 12:00:00
    MessageType messageType = TEXTTYPE; //消息类型
    UserInfo sender = UserInfo();       //发送者信息
    QByteArray content = QByteArray();  //消息的正文内容
    QString fileId = "";                //文件的身份标识. 当消息类型为文件, 图片, 语音 的时候, 才有效. 当消息类型为 文本, 则为 ""
    QString fileName = "";              //文件名称. 只是当消息类型为 文件 消息, 才有效. 其他消息均为 ""

    // 此处 extraInfo 目前只是在消息类型为文件消息时, 作为 "文件名" 补充.
    static Message makeMessage(MessageType messageType, const QString& chatSessionId, const UserInfo& sender,
                               const QByteArray& content, const QString& extraInfo) {
        if (messageType == TEXTTYPE) {
            return makeTextMessage(chatSessionId, sender, content);
        } else if (messageType == IMAGETYPE) {
            return makeImageMessage(chatSessionId, sender, content);
        } else if (messageType == FILETYPE) {
            return makeFileMessage(chatSessionId, sender, content, extraInfo);
        } else if (messageType == SPEECHTYPE) {
            return makeSpeechMessage(chatSessionId, sender, content);
        } else {
            // 触发了未知的消息类型
            return Message();
        }
    }

private:
    // 此处需要确保, 设置的 messageId 是 "唯一" 的
    static QString makeId(){
        return "M"+QUuid::createUuid().toString().mid(25,12);
    }

    static Message makeTextMessage(const QString& chatSessionId, const UserInfo& sender, const QByteArray& content) {
        Message message;
        message.messageId = makeId();
        message.chatSessionId = chatSessionId;
        message.sender = sender;
        message.time = formatTime(getTime());   // 生成一个格式化时间
        message.content = content;
        message.messageType = TEXTTYPE;
        message.fileId = "";
        message.fileName = "";
        return message;
    }

    static Message makeImageMessage(const QString& chatSessionId, const UserInfo& sender, const QByteArray& content) {
        Message message;
        message.messageId = makeId();
        message.chatSessionId = chatSessionId;
        message.sender = sender;
        message.time = formatTime(getTime());
        message.content = content;
        message.messageType = IMAGETYPE;
        //fileId 后续使用的时候再进一步设置
        message.fileId = "";
        //fileName 不使用, 直接设为 ""
        message.fileName = "";
        return message;
    }

    static Message makeFileMessage(const QString& chatSessionId, const UserInfo& sender, const QByteArray& content, const QString& fileName) {
        Message message;
        message.messageId = makeId();
        message.chatSessionId = chatSessionId;
        message.sender = sender;
        message.time = formatTime(getTime());
        message.content = content;
        message.messageType = FILETYPE;
        //fileId 后续使用的时候进一步设置
        message.fileId = "";
        message.fileName = fileName;
        return message;
    }

    static Message makeSpeechMessage(const QString& chatSessionId, const UserInfo& sender, const QByteArray& content) {
        Message message;
        message.messageId = makeId();
        message.chatSessionId = chatSessionId;
        message.sender = sender;
        message.time = formatTime(getTime());
        message.content = content;
        message.messageType = SPEECHTYPE;
        // fileId 后续使用的时候进一步设置
        message.fileId = "";
        // fileName 不使用, 直接设为 ""
        message.fileName = "";
        return message;
    }
};

//会话信息
class ChatSessionInfo{
public:
    QString chatSessionId = "";         //会话编号
    QString chatSessionName = "";       //会话名字
    Message lastMessage = Message();    //表示最新的消息
    QIcon avatar = QIcon();             //会话头像
    QString userId = "";                //用户编号
};

}//end model
